namespace srl {
    
    template<class T>
    Vector<T>::Vector() {
        
    }
    
    template<class T>
    Vector<T>::Vector(T a, T b, T c, T d) {
        x = a;
        y = b;
        z = c;
        w = d;
    }
    template<class T>
    Vector<T>::Vector(T a, T b, T c) {
        x = a;
        y = b;
        z = c;
        w = T();
    }
    
    template<class T>
    Vector<T>::Vector(const Vector<T> &v) {
        x = v.x;
        y = v.y;
        z = v.z;
        w = v.w;
    }
    
    template<class T>
    Vector<T>::~Vector() {
        
    }
    
    
    
    // All operators
    
    template<class T>
    srl::Vector<T>&   Vector<T>::operator+= (const Vector<T> &v) {
        x += v.x; y += v.y; z += v.z;
        return *this;
    }
    
    template<class T>
    srl::Vector<T>   Vector<T>::operator+ (const Vector<T> &v) {
        return Vector<T>(x+v.x, y+v.y, z+v.z);
    }
    template<class T>
    srl::Vector<T>   Vector<T>::operator+ (const T &v) {
        return Vector<T>(x+v, y+v, z+v);
    }
    
    template<class T>
    srl::Vector<T>& Vector<T>::operator-= (const Vector<T> &v) {
        x -= v.x; y -= v.y; z -= v.z;
        return *this;
    }
    
    template<class T>
    srl::Vector<T>  Vector<T>::operator- (const Vector<T> &v) {
        return Vector<T>(x-v.x, y-v.y, z-v.z);
    }
    
    template<class T>
    srl::Vector<T>& Vector<T>::operator*= (const int a) {
        x *= a; y *= a; z *= a;
        return *this;
    }
    
    template<class T>
    srl::Vector<T>  Vector<T>::operator* (const Vector<T> &v ) {
        return Vector<T>(x*v.x, y*v.y, z*v.z);
    }
    
    template<class T>
    srl::Vector<T>& Vector<T>::operator/= (const int a) {
        x /= a; y /= a; z /= a;
        return *this;
    }
    
    template<class T>
    srl::Vector<T>  Vector<T>::operator/ (const Vector<T> &v ) {
        return Vector<T>(x/v.x, y/v.y, z/v.z);
    }
    
    
    template<class T>   
    srl::Vector<T>  Vector<T>::operator* (const int a) {
        return Vector<T>(x/a, y/a, z/a);
    }
    
    template<class T>
    srl::Vector<T>  Vector<T>::operator/ (const int a) {
        if(a!=0)
            return Vector<T>(x/a, y/a, z/a);
    }
    
    template<class T>
    bool Vector<T>::operator!= ( const Vector<T> &v ) {
        return (x != v.x || y != v.y || z != v.z); 
    }
    
    template<class T>
    T &Vector<T>::operator[] ( const int i ) {
    	switch(i) {
    		case 0: return x; break;
    		case 1: return y; break;
    		case 2: return z; break;
    		case 3: return w; break;
    	}
    }
    template<class T>
	void Vector<T>::cross( const Vector<T> &v ) {
		x = y*v.z - z*v.y;
		y = z*v.x - x*v.z;
		z = x*v.y - y*v.x;
	}
	template<class T>
	void Vector<T>::cross( const Vector<T> &v1, const Vector<T> &v2 ) {
		x = v1.y*v2.z - v1.z*v2.y;
		y = v1.z*v2.x - v1.x*v2.z;
		z = v1.x*v2.y - v1.y*v2.x;
	}
    template<class T>
    T  Vector<T>::dot (const Vector<T> &v ) { 
    	return x*v.x + y*v.y + z*v.z;
    }
    
    template<class T>
    T Vector<T>::All() {
        return x+y+z;
    }
    
    // Return the length of the vector
    template<class T>
    float Vector<T>::Length() {
        return sqrt(x*x + y*y + z*z);
    }
    
    // Normalize the vector
    template<class T>
    void Vector<T>::Normalize() {
        float l = Length();
        x /= l;
        y /= l;
        z /= l;
    }
    
};
